package com.hioove.core.web.mvc.model;

import com.hioove.core.aop.model.InterceptorContext;
import com.hioove.core.model.base.config.MethodSupport;
import com.hioove.core.reflect.SqlProxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public class SqlCglibProxy extends SqlProxy implements MethodInterceptor {

    static Logger log = LoggerFactory.getLogger(SqlProxy.class);
    // 用于aop拦截器中间变量
    final static ThreadLocal<InterceptorContext<?>> INTERCEPTOR_CONTEXT = new ThreadLocal<>();

    @Override
    public <T> T create(Class<T> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return (T) enhancer.create();
    }

    @Override
    public void init() {

    }

    @Override
    public void destroy() {

    }

    // 接口型类 实现方法调用 主要是dao层数据
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

        // mybatis动态代理
        // Object proxyResult = proxy.invokeSuper(obj, args);
        Object proxyResult = new Object();
        // 清理中间变量
        remove();
        return proxyResult;
    }

    private void process(List<MethodSupport> interceptMission) {
        Optional.ofNullable(interceptMission).orElse(Collections.emptyList()).stream().sorted(Comparator.comparing((MethodSupport methodSupport) -> methodSupport.getClassSupport().getInstance().hashCode())).forEach(methodSupport -> {
            Object[] param = methodSupport.getMethod().getParameterCount() == 0 ? new Object[]{} : new Object[]{Optional.ofNullable(INTERCEPTOR_CONTEXT.get()).orElse(new InterceptorContext<>())};
            try {
                Object invoke = methodSupport.getMethod().invoke(methodSupport.getClassSupport().getInstance(), param);
                Stream.of(param.length).filter(integer -> integer != 0).forEach(integer -> INTERCEPTOR_CONTEXT.set((InterceptorContext<?>) invoke));
            } catch (Exception e) {
                log.error("Proxy object exception!!!", e);
            }

        });
    }

    public static void remove() {
        INTERCEPTOR_CONTEXT.remove();
    }


}
